package com.after.saas.file.task;

import cn.hutool.core.collection.ListUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;

/**
 * @author hjchen
 * @Classname AutoTask
 * @Description TODO
 * @auth after
 * @since 2023/6/3 12:17
 */

@Slf4j
@Component
public class AutoTask {

    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
    private final static List<ScheduledExecutorService> SCHEDULED_EXECUTOR_SERVICES = new ArrayList<>();


    public AutoTask(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
        this.threadPoolTaskExecutor = threadPoolTaskExecutor;
    }

    //    @PostConstruct
    public void start() {
        ScheduledExecutorService executorService = newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(() -> {
            for (int i : getList()) {
                try {
                    if (i == 6) {
                        System.out.println("result=" + (5 / 0));
                    }
                } catch (Throwable e) {
                    log.info("系统异常：", e);
                }
                log.info("threadId:{},childNum {}", Thread.currentThread().getId(), i);
            }
        }, 1, 10, TimeUnit.SECONDS);
    }

    //    @Async(value = "threadPoolTaskScheduler")
//    @Scheduled(cron = "0/5 * * * * ?")
    public void cronChildTask() {
        log.info("threadId:{},cronChildTask...", Thread.currentThread().getId());
        threadPoolTaskExecutor.execute(new ChildTask(getList()));
//        threadPoolTaskExecutor.execute(new ChildTask(integers.size()));
        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        System.out.println("线程总数为 = " + bean.getThreadCount());
    }

    //    @Scheduled(cron = "30/5 * * * * ?")
    public void cronMainTask() throws InterruptedException {
        List<Integer> integers = getList();
        log.info("threadId:{},cronEchoTask,integers {}...", Thread.currentThread().getId(), integers);
        for (int i : integers) {
            threadPoolTaskExecutor.execute(new EchoTask(i));
        }
        Thread.sleep(5 * 1000);
    }

    public static class ChildTask implements Runnable {

        private final List<Integer> integers;

        public ChildTask(List<Integer> integers) {
            this.integers = integers;
        }

        @SneakyThrows
        @Override
        public void run() {
            log.info("threadId:{}开始执行...", Thread.currentThread().getId());
            for (int i : integers) {
                log.info("threadId:{},childNum {}", Thread.currentThread().getId(), i);
            }
            try {
                Thread.sleep(10 * 1000);
            } catch (InterruptedException e) {
                log.error("interrupted error: {}", e.getMessage());
            }
        }
    }


    public static class EchoTask implements Runnable {

        private final int i;

        public EchoTask(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            log.info("echoNum {}", i);
        }
    }

    public List<Integer> getList() {
        List<Integer> integers = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            integers.add(i);
        }
        return integers;
    }

//    @PostConstruct
    public void testScheduledExecutorService() {
        List<Integer> integers = getList();
        List<List<Integer>> lists = ListUtil.split(integers, 5);
        for (List<Integer> list : lists) {
            ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
            SCHEDULED_EXECUTOR_SERVICES.add(executorService);
            executorService.scheduleAtFixedRate(new ChildTask(list), 10, 10, TimeUnit.SECONDS);
        }
    }

    @Scheduled(initialDelay = 1000, fixedRate = 10 * 1000)
    public void testScheduledExecutor() {
        List<List<Integer>> lists = ListUtil.split(getList(), 10);
        for (List<Integer> list : lists) {
            threadPoolTaskExecutor.execute(new ChildTask(list));
        }
    }

    public static class MyRunnable implements Runnable {

        private final int i;

        public MyRunnable(int i) {
            this.i = i;
        }

        @SneakyThrows
        @Override
        public void run() {
            log.info("i={}", i);
            ThreadMXBean bean = ManagementFactory.getThreadMXBean();
            System.out.println("线程总数为 = " + bean.getThreadCount());
        }
    }

    @PreDestroy
    public void preDestroy() {
        log.info("task is destroyed...");
        for (ScheduledExecutorService executorService : SCHEDULED_EXECUTOR_SERVICES) {
            executorService.shutdown();
        }
    }
}
